package cn.edu.xjtu.carlWay.tree.preAndInConstructBinaryTree;

import cn.edu.xjtu.Util.TreeNode.TreeNode;

/**
 * 105. 从前序与中序遍历序列构造二叉树
 * 给定两个整数数组 preorder 和 inorder ，其中 preorder 是二叉树的先序遍历， inorder 是同一棵树的中序遍历，请构造二叉树并返回其根节点。
 * <p>
 * https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
 */
public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return helpBuild(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }

    private TreeNode helpBuild(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight) {
        if (inRight - inLeft == 0) {
            return null;
        }
        if (inRight - inLeft == 1) {
            return new TreeNode(inorder[inLeft]);
        }
        TreeNode root = new TreeNode(preorder[preLeft]);
        int rootIndex = 0;
        for (int i = inLeft; i < inRight; i++) {
            if (inorder[i] == root.val) {
                rootIndex = i;
                break;
            }
        }

        root.left = helpBuild(preorder, preLeft + 1, preLeft + 1 + (rootIndex - inLeft), inorder, inLeft, rootIndex);
        root.right = helpBuild(preorder, preLeft + 1 + (rootIndex - inLeft), preRight, inorder, rootIndex + 1, inRight);

        return root;
    }
}
